commonlibsse_ng\re\c/
ControlMap.rs1use crate::re::BSFixedString::BSFixedString;
2use crate::re::BSInputDeviceManager::BSInputDeviceManager;
3use crate::re::BSTArray::BSTArray;
4use crate::re::BSTEvent::BSTEventSource;
5use crate::re::InputDevices::{INPUT_DEVICE, INPUT_DEVICE_VR_CEnum};
6use crate::re::PCGamepadType::PC_GAMEPAD_TYPE_CEnum;
7use crate::re::UserEventEnabled::UserEventEnabled;
8use crate::re::UserEvents::{INPUT_CONTEXT_ID, INPUT_CONTEXT_ID_VR_CEnum, USER_EVENT_FLAG};
9use crate::rel::module::ModuleState;
10use crate::rel::relocation::{RelocationError, raw_pointer_as_mut, raw_pointer_as_ref};
11use crate::skse::version::RUNTIME_SSE_1_6_1130;
12
13#[repr(C)]
14#[derive(Debug)]
15pub struct ControlMap {
16 pub __base: [u8; 1], pub __base1: BSTEventSource<UserEventEnabled>, pub controlMap: [*mut InputContext; INPUT_CONTEXT_ID_VR_CEnum::count()], }
20const _: () = assert!(core::mem::size_of::<ControlMap>() == 0xE8);
21
22impl ControlMap {
23 #[commonlibsse_ng_derive_internal::relocate(
25 cast_as = "*mut *mut ControlMap",
26 default = "None",
27 deref_once,
28 id(se = 514705, ae = 400863)
29 )]
30 pub fn get_singleton() -> Option<&'static ControlMap> {
31 |deref_type: DerefType| unsafe { deref_type.as_ref() }
32 }
33
34 #[commonlibsse_ng_derive_internal::relocate(
36 cast_as = "*mut *mut ControlMap",
37 default = "None",
38 deref_once,
39 id(se = 514705, ae = 400863)
40 )]
41 pub fn get_singleton_mut() -> Option<&'static mut ControlMap> {
42 |deref_type: DerefType| unsafe { deref_type.as_mut() }
43 }
44
45 pub fn get_runtime_data(&self) -> Result<&RUNTIME_DATA, RelocationError> {
51 let (is_vr, is_ae_1_6_1130) = ModuleState::map_or_init(|module| {
52 (module.runtime.is_vr(), module.version >= RUNTIME_SSE_1_6_1130)
53 })?;
54
55 let this = self as *const Self;
56 let member_ptr = if is_ae_1_6_1130 {
57 this.wrapping_offset(0xf0).cast()
58 } else {
59 let offset = if is_vr { 0xE8 } else { 0x108 };
60 this.wrapping_offset(offset).cast()
61 };
62
63 Ok(unsafe { raw_pointer_as_ref(member_ptr) }?)
64 }
65
66 pub fn get_runtime_data_mut(&mut self) -> Result<&mut RUNTIME_DATA, RelocationError> {
72 let (is_vr, is_ae_1_6_1130) = ModuleState::map_or_init(|module| {
73 (module.runtime.is_vr(), module.version >= RUNTIME_SSE_1_6_1130)
74 })?;
75
76 let this = self as *mut Self;
77
78 let member_ptr = if is_ae_1_6_1130 {
79 this.wrapping_offset(0xf0).cast()
80 } else {
81 let offset = if is_vr { 0xE8 } else { 0x108 };
82 this.wrapping_offset(offset).cast()
83 };
84
85 Ok(unsafe { raw_pointer_as_mut(member_ptr) }?)
86 }
87
88 pub fn allow_text_input(&mut self, allow: bool) -> Option<i8> {
89 let text_entry_count = &mut (self.get_runtime_data_mut().ok()?.textEntryCount);
90
91 if allow {
92 if *text_entry_count != -1 {
93 *text_entry_count += 1;
94 }
95 } else if *text_entry_count != 0 {
96 *text_entry_count -= 1;
97 }
98
99 Some(*text_entry_count)
100 }
101
102 pub fn get_button_name_from_user_event(
103 &self,
104 event_id: &BSFixedString,
105 device: INPUT_DEVICE,
106 ) -> Option<BSFixedString> {
107 for input_context in self.controlMap {
108 let Some(input_context) = (unsafe { input_context.as_ref() }) else {
109 continue;
110 };
111
112 let device_mappings = input_context.deviceMappings.get(device.0 as usize)?;
113
114 for mapping in device_mappings {
115 if mapping.eventID != *event_id {
116 continue;
117 }
118
119 let input_key = mapping.inputKey;
120 if input_key == 0xFF {
121 break;
122 }
123
124 let input_device_manager = BSInputDeviceManager::get_singleton_mut()?;
125 if let Some(output) =
126 input_device_manager.get_button_name_from_id(device, input_key as u32)
127 {
128 return Some(output);
129 };
130 }
131 }
132
133 None
134 }
135
136 pub fn get_user_event_name(
137 &self,
138 button_id: u32,
139 device: INPUT_DEVICE,
140 context: INPUT_CONTEXT_ID,
141 ) -> Option<&BSFixedString> {
142 let input_ctx = self.controlMap.get(context.0 as usize)?;
143 let mappings = unsafe { input_ctx.as_ref() }?.deviceMappings.get(device.0 as usize)?;
144
145 let search_target_key = button_id as u16;
147 let slice = mappings.as_slice();
148 let start = slice.partition_point(|x| x.inputKey < search_target_key);
149 let end = slice.partition_point(|x| x.inputKey <= search_target_key);
150
151 if end - start == 1 { Some(&slice[start].eventID) } else { None }
152 }
153
154 #[commonlibsse_ng_derive_internal::relocate_fn(se_id = 67244, ae_id = 68544)]
155 #[inline]
156 pub fn pop_input_context(&mut self, context: INPUT_CONTEXT_ID) -> bool {}
157
158 #[commonlibsse_ng_derive_internal::relocate_fn(se_id = 67243, ae_id = 68543)]
159 #[inline]
160 pub fn push_input_context(&mut self, context: INPUT_CONTEXT_ID) -> bool {}
161}
162
163#[repr(C)]
164#[derive(Debug, Clone)]
165pub struct RUNTIME_DATA {
166 pub linkedMappings: BSTArray<LinkedMapping>, pub contextPriorityStack: BSTArray<INPUT_CONTEXT_ID>, pub enabledControls: USER_EVENT_FLAG, pub unk11C: USER_EVENT_FLAG, pub textEntryCount: i8, pub ignoreKeyboardMouse: bool, pub ignoreActivateDisabledEvents: bool, pub pad123: u8, pub gamePadMapType: PC_GAMEPAD_TYPE_CEnum, }
176
177#[repr(C)]
178#[derive(Debug, Clone)]
179pub struct UserEventMapping {
180 pub eventID: BSFixedString, pub inputKey: u16, pub modifier: u16, pub indexInContext: i8, pub remappable: bool, pub linked: bool, pub userEventGroupFlag: USER_EVENT_FLAG, pub pad14: u32, }
189const _: () = assert!(core::mem::size_of::<UserEventMapping>() == 0x18);
190
191#[repr(C)]
192#[derive(Debug, Clone)]
193pub struct InputContext {
194 pub deviceMappings: [BSTArray<UserEventMapping>; INPUT_DEVICE_VR_CEnum::count()], }
196const _: () = assert!(core::mem::size_of::<InputContext>() == 0xF0);
197
198#[repr(C)]
199#[derive(Debug, Clone, PartialEq)]
200pub struct LinkedMapping {
201 pub linkedMappingName: BSFixedString, pub linkedMappingContext: INPUT_CONTEXT_ID, pub device: INPUT_DEVICE, pub linkFromContext: INPUT_CONTEXT_ID, pub pad14: u32, pub linkFromName: BSFixedString, }
208const _: () = assert!(core::mem::size_of::<LinkedMapping>() == 0x20);